using System.Configuration;
using System.Web;
using System.Xml;
using System;

/*	-----------------------------------------------------------------------	
	Copyright:	umlungu consulting (pty) ltd
	Author:		Alan Benington	
	Started:	2006-07-10	
	Status:		release	
	Version:	2.0.0
	Buidl:		20070524
	License:	GNU General Public License
	-----------------------------------------------------------------------	*/

/*	-----------------------------------------------------------------------	
	Development Notes:
	==================
	20070524:	Modification for .Net 2.0
	20070703:	Removed net_2_0 directive (from compatibility build)
	-----------------------------------------------------------------------	*/

namespace umlungu.engineX.blogX {
	/// <summary>The model used for the pages on the website</summary>
	public enum x_blogSiteModel {
		/// <summary>displayX derived site pages</summary>
	    displayX = 1,
		/// <summary>uiX derived site pages</summary>
	    uiX = 2
	}
	/// <summary>
	/// The x_glitch class is used for presentation of pages when things go wrong.
	/// <para>This class is based on an exception, but allows for the following</para>
	/// <para> - a set of glitches to be defined in a template file (typically templates/errorX.xml)</para>
	/// <para> - the loading of a glitch (identified by its unique name)</para>
	/// <para></para>
	/// <para></para>
	/// <para></para>
	/// <para>Note:</para>
	/// <para>This class has not been fully developed. It allows for the class to be used regardless of the 'style' of site (eg website vs blogsite)</para>
	/// <para>However the development to date has focussed on blogsites</para>
	/// </summary>
	public class x_glitch : x_exception{
		#region Invisible properties
		private static bool preload = false;
		private HttpApplicationState application;
		private uiX uipage;
		#endregion

		#region Error String constants
		private const string error_errors_name = "Error has not been defined.";
		private const string error_errors_list = "Errors have not been loaded.";
		private const string error_error_elem = "Error has not been loaded.";
		private const string error_space_name = "Spaces are not defined ('spaces' parameter missing?)";
		private const string error_space_list = "Space list is empty ('spaces' parameter missing?)";
		private const string error_blogs_name = "Blogs are not defined ('blogs' parameter missing?)";
		private const string error_blogs_list = "Blog list is empty ('blogs' parameter missing?)";
		#endregion

		#region Visible properties
		private XmlElement error;
		/// <summary>The error reference element</summary>
		/// <value>XmlElement that contains the error reference</value>
		public XmlElement Error {
			get { return error; }
		}
		private XmlDocument errors;
		/// <summary>The error template document</summary>
		/// <value>XmlDocument that contains the error references</value>
		public XmlDocument Errors {
			get { return errors; }
		}
		private string errorName;
		/// <summary>Identifying error name value</summary>
		/// <value>String value to identify the error, empty if error not used</value>
		public string ErrorName {
			get { return errorName; }
			set { errorName = value; loadError(); }
		}
		private string name;
		/// <summary>Identifying name value</summary>
		/// <value>String value to identify the xsl, css and js to be loaded</value>
		public string Name {
			get { return name; }
			set { name = value; }
		}
		private string space;
		/// <summary>Spaces identifying value</summary>
		/// <value>String value to identify the (blog)spaces to be displayed</value>
		public string Space {
			get { return space; }
			set { space = value; }
		}
		private string page;
		/// <summary>Definiton of the page</summary>
		/// <value>Description of the value of the page</value>
		public string Page {
			get { return page; }
			set { page = value; }
		}
		private string topic;
		/// <summary>Current topic</summary>
		/// <value>String value to identify the current (blog)topic</value>
		public string Topic {
			get { return topic; }
			set { topic = value; }
		}
		private string archive;
		/// <summary>Definiton of the archive</summary>
		/// <value>Description of the value of the archive</value>
		public string Archive {
			get { return archive; }
			set { archive = value; }
		}
		private string blog;
		/// <summary>Blog identifying value</summary>
		/// <value>String value to identify the blog to be displayed</value>
		public string Blog {
			get { return blog; }
			set { blog = value; }
		}
		private string blogs;
		/// <summary>Blogs identifying value</summary>
		/// <value>String value to identify the blogs to be displayed</value>
		public string Blogs {
			get { return blogs; }
			set { blogs = value; }
		}
		private string author;
		/// <summary>Definiton of the author</summary>
		/// <value>Description of the value of the author</value>
		public string Author {
			get { return author; }
			set { author = value; }
		}
		#endregion

		#region Constructors/Destructors
		/// <overloads>Constructor</overloads>
		/// <summary>Default constructor</summary>
		/// <param name="pge">The web application uiX page object</param>
		/// <param name="cde">Error code</param>
		/// <param name="msg">Error message</param>
		public x_glitch(uiX pge, string cde, string msg) : base(cde, msg) {
			errorName = cde;
			initialise(pge);
		}
		/// <summary>Constructor description</summary>
		/// <param name="pge">The web application uiX page object</param>
		/// <param name="cde">Error code</param>
		/// <param name="msg">Error message</param>
		/// <param name="err">The name of the glitch error</param>
		public x_glitch(uiX pge, string cde, string msg, string err) : base(cde, msg) {
			errorName = err;
			initialise(pge);
		}
		#endregion

		#region Public methods
		#endregion
		
		#region Protected methods
		#endregion
				
		#region Private methods
		/// <summary>Check and return parameter (or default value)</summary>
		private string getParam(string param, string def) {
			string thisparam = "";
			if (error == null)
				throw(new x_exception("error_error_elem", error_error_elem));
			// first check in the attributes of the error node itself (eg feed, poll, tip etc)
			if (param != "name")	// dont check parent if 'name'
				thisparam = error.GetAttribute(param);
			if (isNothing(thisparam)) {
				XmlElement paramnode = (XmlElement)error.SelectSingleNode("blog");
				if (paramnode != null) {
					thisparam = paramnode.GetAttribute(param);
					if (isNothing(thisparam)) {	// look in parent if null
						paramnode = (XmlElement)error.ParentNode.SelectSingleNode("blog");
						if (paramnode != null)
							thisparam = paramnode.GetAttribute(param);
					}
				}
			}
			return (isNothing(thisparam))? def : thisparam;
		}
		/// <summary>Checks if a string is empty or null.</summary>
		private bool isNothing(string thisstring) {
			return (thisstring == null || String.Compare(thisstring, "") == 0)? true : false;
		}
		private bool isThing(string thisstring) {
			return (thisstring != null && String.Compare(thisstring, "") != 0)? true : false;
		}
		/// <summary>Initialise the error object.</summary>
		private void initialise(uiX pge) {
			uipage = pge;
			application = uipage.Application;
			loadErrors();
			loadError();
		}
		/// <summary>Gets the errors xml document.</summary>
		private void loadErrors() {
			if (preload)
				errors = (XmlDocument) application["ErrorX"];
			else {
				errors = new XmlDocument();
				x_config config = new x_config();
				errors.Load(uipage.Server.MapPath(String.Concat(config.Path, "templates/errorX.xml")));
			}
		}
		/// <overloads>Loads a error reference from the errors list document</overloads>
		/// <summary>Assumes the errorName is defined and throws exception if cannot load error</summary>
		private void loadError() {
			if (errors == null)
				throw (new x_exception("error_errors_list", error_errors_list));
			if (errorName == null | errorName == "")
				throw (new x_exception("error_errors_name", error_errors_name));
			error = (XmlElement)errors.SelectSingleNode(String.Concat("/website/errors/error[@name='", errorName, "']"));
			if (error == null)
				error = (XmlElement)errors.SelectSingleNode("/website/error[@name='default']");
			if (error == null)
				throw (new x_exception("error_error_elem", error_error_elem + ":" + errorName));
			space = getParam("space", "");
			page = getParam("page", "");
			topic = getParam("topic", "");
			archive = getParam("archive", "");
			blog = getParam("id", "");
			blogs = getParam("ids", "");
			author = getParam("author", "");
		}
		#endregion
	}
}
